'use strict';

const Controller = require('egg').Controller;
const _ = require('lodash');
const utils = require('../utils/utils');

class CampaignController extends Controller {
  async create() {
    const ctx = this.ctx;
    try {
      ctx.validate({
        start: 'string',
        end: 'string',
        picUrl: 'string',
        entryUrl: 'string',
        title: 'string',
        pcode: 'string',
      });

      const body = this.ctx.request.body;
      const awards = body.awards || [];
      delete body.awards;

      const campaign = await ctx.app.model.Campaign.create(Object.assign(body, {
        creator: {
          operator_id: ctx.v._id,
          realname: ctx.v.realname,
        },
      }));

      awards.map(async item => {
        ctx.validate({
          limit: {type: 'int'},
          _id: {type: 'string'},
          probability: {type: 'int'},
        }, item)
        item.remain = item.limit;
        await ctx.service.campaign.addCampaignAward(campaign._id, item._id, item);
      });

      this.ctx.body = {
        code: 0,
        msg: '保存成功',
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }

  async list() {
    const ctx = this.ctx;
    try {
      const query = this.ctx.request.query;
      const data = {
        pageIndex: +query.pageIndex,
        pageSize: +query.pageSize,
        title: query.title || '',
        pcode: query.pcode || '',
      };
      ctx.validate({
        pageIndex: {type: 'int', min: '1'},
        pageSize: {type: 'int', min: '1'},
      }, data);

      const result = await this.ctx.service.campaign.list(data);

      this.ctx.body = {
        code: 0,
        data: result,
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }

  async update() {
    const ctx = this.ctx;
    try {
      this.ctx.validate({
        id: 'string',
      }, ctx.params);

      const body = ctx.request.body;
      const id = ctx.params.id;
      const campaign = await ctx.app.model.Campaign.findById(id);
      if (!campaign) {
        throw new Error('没有这个活动');
      }
      if (Object.keys(body).length === 1 && typeof body.enabled === 'boolean') {
        await ctx.service.campaign.changeStatus(ctx.params.id, body.enabled);
      } else {
        let mix = utils.mix(campaign.awards.toObject(), body.awards, '_id');
        for (let type in mix) {
          for (let v of mix[type]) {
            v._id = v._id.toString();
            ctx.validate({
              limit: {type: 'int'},
              _id: {type: 'string'},
              probability: {type: 'int'},
            }, v);
            switch (type) {
              case 'update':
                let oldAward = _.find(campaign.awards, awards => {
                  return v._id === awards._id.toString();
                });
                v.inc = v.limit - oldAward.limit;
                if (oldAward.remain + v.inc < 0) {
                  throw new Error(`该奖品数量限制${oldAward.limit}, 已发放${oldAward.limit - oldAward.remain}, 不能数量减少到${v.limit}`);
                }
                await ctx.service.campaign.updateCampaignAward(id, v._id, v);
                break;
              case 'add':
                v.remain = v.limit;
                await ctx.service.campaign.addCampaignAward(id, v._id, v);
                break;
              case 'del':
                await ctx.service.campaign.deleteCampaignAward(id, v._id, v);
                break;
              default:
                break;
            }
          }
        }
        await this.ctx.service.campaign.update(this.ctx.params.id, body);
      }
      this.ctx.body = {
        code: 0,
        msg: '更新成功',
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }

  async delete() {
    const ctx = this.ctx;
    try {
      ctx.validate({
        id: 'string',
      }, ctx.params);
      const id = ctx.params.id;
      const campaign = await ctx.app.model.Campaign.findById(id);
      if (!campaign) {
        throw new Error('没有这个活动');
      }
      campaign.awards.map(async item => {
        await ctx.service.campaign.deleteCampaignAward(id, item._id);
      });
      await this.ctx.service.campaign.delete(id);
      this.ctx.body = {
        code: 0,
        msg: '删除成功',
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }

  async get() {
    const ctx = this.ctx;
    try {
      ctx.validate({
        id: 'string',
      }, ctx.params);

      const id = ctx.params.id;

      let campaign = await ctx.app.model.Campaign.findOne({
        _id: id,
      });
      campaign = campaign.toObject();
      let tempAwards = [];
      for (let item of campaign.awards) {
        let tempAward = await ctx.app.model.Award.findById(item._id);
        item.used = item.limit - item.remain;
        item.max = item.limit + tempAward.remaining_inventory;
        tempAwards.push(item);
      }
      campaign.awards = tempAwards;
      ctx.body = {
        code: 0,
        data: campaign,
        msg: '查询成功',
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }

  async search() {
    const query = this.ctx.request.query;
    const condition = {};
    condition.deleted = false;

    if (query.product_type) {
      condition.pcode = query.product_type;
    }

    const campaigns = await this.ctx.app.model.Campaign.aggregate([{
      $match: condition
    }, {
      $unwind: '$awards'
    }, {
      $group: {
        _id: {_id: '$_id', award_type: '$awards.type'},
        title: {$first: '$title'},
      },

    }, {
      $group: {
        _id: {_id: '$_id._id'},
        awardsTypes: {$push: '$_id.award_type'},
        title: {$first: '$title'},
      },
    }]);
    let result = [];
    for (let item of campaigns) {
      item._id = item._id._id;
      result.push(item);
    }
    this.ctx.body = {
      code: 0,
      data: {
        list: result,
      },
    };
  }

  async updateConfig() {
    const ctx = this.ctx;
    try {
      this.ctx.validate({
        id: 'string',
      }, ctx.params);

      const body = ctx.request.body;
      const id = ctx.params.id;
      const campaign = await ctx.app.model.Campaign.findById(id);
      if (!campaign) {
        throw new Error('没有这个活动');
      }
      await ctx.app.model.Campaign.update({_id: id}, body);
      const newer = await ctx.app.model.Campaign.findById(id);
      this.ctx.body = {
        code: 0,
        msg: '更新成功',
        data: {
          older: campaign,
          newer: newer,
        }
      };
    } catch (e) {
      ctx.body = {
        code: 1,
        msg: `${e.message}`,
      };
      ctx.logger.error(e);
    }
  }
}

module.exports = CampaignController;
